package com.uzai.console.service.dingding.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkservice_group_1_0.models.CreateGroupHeaders;
import com.aliyun.dingtalkservice_group_1_0.models.CreateGroupRequest;
import com.aliyun.dingtalkservice_group_1_0.models.CreateGroupResponse;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.common.dto.god.ExclusiveGroupOptDto;
import com.uzai.common.enums.DeviceAuthTypeEnum;
import com.uzai.common.enums.PaymentTypeEnum;
import com.uzai.common.enums.RedisCacheKeyEnum;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.common.utils.Math;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.DingExclusiveGroupUtils;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.dto.alipaydetail.AlipayDetailCreateDto;
import com.uzai.console.dto.dingding.DingWarningGroupBuyMsgDto;
import com.uzai.console.dto.dingding.DingWarningGroupDto;
import com.uzai.console.dto.dingding.DingWarningGroupQuery;
import com.uzai.console.entity.*;
import com.uzai.console.enums.AlipayStatusEnum;
import com.uzai.console.enums.AlipayTypeEnum;
import com.uzai.console.enums.MerAccDetailSourceTypeEnum;
import com.uzai.console.mapper.AlipayDetailMapper;
import com.uzai.console.mapper.DingWarningGroupMapper;
import com.uzai.console.mapper.MerchantMapper;
import com.uzai.console.service.alipaydetail.AlipayDetailService;
import com.uzai.console.service.dingding.DingWarningGroupService;
import com.uzai.console.vo.alipaydetail.businessinfo.DingWarningGroupMsgBuyBusinessInfo;
import com.uzai.console.vo.alipaydetail.businessinfo.KuaiZhanDomianRebuyBusinessInfo;
import com.uzai.console.vo.dingding.DingWarningGroupBuyMsgPriceVo;
import com.uzai.console.vo.dingding.DingWarningGroupBuyMsgVo;
import com.uzai.console.vo.dingding.DingWarningGroupVo;
import com.uzai.console.vo.kuaizhan.CreateSiteVo;
import com.uzai.console.vo.kuaizhan.PublishPageVo;
import com.uzai.console.vo.kuaizhan.PublishSiteVo;
import com.uzai.console.vo.sysdomain.BuySysDomainVo;
import com.uzai.console.vo.sysdomain.SysDomainKuaizhanPriceVo;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class DingWarningGroupServiceImpl implements DingWarningGroupService {

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DingExclusiveGroupUtils dingExclusiveGroupUtils;
    @Autowired
    private com.aliyun.dingtalkservice_group_1_0.Client dingGroupClient;
    @Autowired
    private DingWarningGroupMapper dingWarningGroupMapper;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;
    @Autowired
    private AlipayDetailService alipayDetailService;
    @Autowired
    private AlipayDetailMapper alipayDetailMapper;

    @Override
    public void addDingWarningGroup(DingWarningGroupDto dingWarningGroupDto) {

        if(dingWarningGroupDto.getMerId()==null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "运营商ID为空");
        }

        if(StringUtils.isBlank(dingWarningGroupDto.getGroupName())){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "报警联系人(钉钉群）为空");
        }

        //查询运营商是否存在
        Merchant merchant = merchantMapper.selectById(dingWarningGroupDto.getMerId());
        if(merchant==null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "运营商不存在");
        }

        DingWarningGroup dingWarningGroup = new DingWarningGroup();
        BeanUtils.copyProperties(dingWarningGroupDto,dingWarningGroup);
        int nowTime = DateUtil.getNowTime();
        dingWarningGroup.setId(IdWorker.getId());
        dingWarningGroup.setFreeMsg(uzaiConsoleSysConfig.getDingdingWarningGroupFreeMsgNum());
        dingWarningGroup.setFreeUsedMsg(0);
        dingWarningGroup.setFreeMsgUpdateTime(nowTime);
        dingWarningGroup.setFreeUsedTotal(0);
        dingWarningGroup.setPayMsg(0);
        dingWarningGroup.setPayUsedMsg(0);
        dingWarningGroup.setCreateTime(nowTime);
        dingWarningGroup.setUpdateTime(nowTime);

        //获取创建钉钉群的基本参数
        Object o = redisTemplate.opsForValue().get(RedisCacheKeyEnum.DING_DING_WARNING_GROUP.getKey());
        if (o == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "获取钉钉专属服务群配置失败");
        }
        ExclusiveGroupOptDto ex = JSONObject.parseObject(o.toString(), ExclusiveGroupOptDto.class);

        //获取token
        String accessToken = dingExclusiveGroupUtils.getAccessToken(ex.getAppKey(),ex.getAppSecret());

        String groupName=ex.getGroupName().replace("[钉钉报警联系人]", Tools.getStr(dingWarningGroup.getGroupName()));

        //创建钉钉专属群
        CreateGroupHeaders createGroupHeaders = new CreateGroupHeaders();
        createGroupHeaders.xAcsDingtalkAccessToken = accessToken;
        CreateGroupRequest createGroupRequest = new CreateGroupRequest()
                .setGroupBizId(String.valueOf(dingWarningGroup.getId()))
                .setOpenTeamId(ex.getOpenTeamId())
                .setOpenGroupSetId(ex.getOpenGroupId())
                .setGroupName(groupName)
                .setOwnerStaffId(ex.getGroupMasterId())
                .setMemberStaffIds(ex.getGroupMemberIds());
        CreateGroupResponse groupWithOptions = null;
        try {
            groupWithOptions = dingGroupClient.createGroupWithOptions(createGroupRequest, createGroupHeaders, new RuntimeOptions());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (groupWithOptions == null || groupWithOptions.getBody() == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "创建钉钉专属群失败");
        }

        //设置返回参数
        DingExclusiveGroupConfig dingExclusiveGroupConfig = new DingExclusiveGroupConfig();
        dingExclusiveGroupConfig.setOpenConversationId(groupWithOptions.getBody().getOpenConversationId());
        dingExclusiveGroupConfig.setGroupUrl(groupWithOptions.getBody().getGroupUrl());
        //默认设置一个最大的时间戳（不过期）
        dingExclusiveGroupConfig.setExpireTime(2147483647);
        dingExclusiveGroupConfig.setIfJoinGroup(0);


        dingWarningGroup.setGroupConfig(Tools.getStrEmpty(JSONObject.toJSONString(dingExclusiveGroupConfig)));
        dingWarningGroupMapper.insert(dingWarningGroup);
    }


    @Override
    public Page<DingWarningGroupVo> queryDingWarningGroupByPage(DingWarningGroupQuery dingWarningGroupQuery) {
        List<DingWarningGroupVo> dingWarningGroupVoList = new ArrayList<>();
        //分页查询
        Page<DingWarningGroup> page = new Page<>();
        dingWarningGroupQuery.convert(page);
        List<DingWarningGroup> dingWarningGroupList = dingWarningGroupMapper.queryDingWarningGroupList(page, dingWarningGroupQuery);
        if(dingWarningGroupList != null && dingWarningGroupList.size() > 0){
            for (DingWarningGroup dingWarningGroup : dingWarningGroupList) {
                DingExclusiveGroupConfig dingExclusiveGroupConfig = JSON.parseObject(dingWarningGroup.getGroupConfig(), DingExclusiveGroupConfig.class);
                DingWarningGroupVo dingWarningGroupVo = new DingWarningGroupVo();
                dingWarningGroupVo.setId(dingWarningGroup.getId());
                dingWarningGroupVo.setGroupName(dingWarningGroup.getGroupName());
                dingWarningGroupVo.setFreeMsg(dingWarningGroup.getFreeMsg());
                dingWarningGroupVo.setFreeUsedMsg(dingWarningGroup.getFreeUsedMsg());
                dingWarningGroupVo.setPayMsg(dingWarningGroup.getPayMsg());
                dingWarningGroupVo.setPayUsedMsg(dingWarningGroup.getPayUsedMsg());
                dingWarningGroupVo.setFreeUsedTotal(dingWarningGroup.getFreeUsedTotal());
                dingWarningGroupVo.setGroupUrl(dingExclusiveGroupConfig.getGroupUrl());
                dingWarningGroupVo.setTipAllMember(dingWarningGroup.getTipAllMember());
                dingWarningGroupVoList.add(dingWarningGroupVo);
            }
        }

        Page<DingWarningGroupVo> dingWarningGroupVoPage = new Page<>();
        BeanUtils.copyProperties(page, dingWarningGroupVoPage);
        dingWarningGroupVoPage.setRecords(dingWarningGroupVoList);
        return dingWarningGroupVoPage;
    }

    @Override
    public void deleDingWarningGroup(DingWarningGroupDto dingWarningGroupDto) {
        if(dingWarningGroupDto.getId()!=null){
                dingWarningGroupMapper.deleById(dingWarningGroupDto.getId());
        }
    }

    @Override
    public void updateWarningGroup(DingWarningGroupDto dingWarningGroupDto) {
        if(dingWarningGroupDto.getId()==null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "主键ID为空");
        }
        //通过ID查看是否有群
        DingWarningGroup dingWarningGroup=dingWarningGroupMapper.queryDingWarningGroupById(dingWarningGroupDto.getId());
        if(dingWarningGroup==null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "群不存在");
        }

        if(StringUtils.isNotBlank(dingWarningGroupDto.getGroupName())){
            dingWarningGroup.setGroupName(dingWarningGroupDto.getGroupName());
        }
        if(dingWarningGroupDto.getTipAllMember()!=null){
            dingWarningGroup.setTipAllMember(dingWarningGroupDto.getTipAllMember());
        }

         dingWarningGroup.setUpdateTime(DateUtil.getNowTime());
         dingWarningGroupMapper.update(dingWarningGroup);

    }

    /**
     * 购买消息价格
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public DingWarningGroupBuyMsgPriceVo findBuyMsgPrice(){
        DingWarningGroupBuyMsgPriceVo dingWarningGroupBuyMsgPriceVo = new DingWarningGroupBuyMsgPriceVo();
        dingWarningGroupBuyMsgPriceVo.setPrice(uzaiConsoleSysConfig.getDingdingWarningGroupBuyPrice());
        dingWarningGroupBuyMsgPriceVo.setBuyMsgNum(uzaiConsoleSysConfig.getDingdingWarningGroupBuyMsgNum());
        return dingWarningGroupBuyMsgPriceVo;
    }

    /**
     * 购买消息
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param dingWarningGroupBuyMsgDto
     * @return null
     */
    public DingWarningGroupBuyMsgVo buyMsg(DingWarningGroupBuyMsgDto dingWarningGroupBuyMsgDto){
        //返回对象
        DingWarningGroupBuyMsgVo dingWarningGroupBuyMsgVo = new DingWarningGroupBuyMsgVo();
        //业务号
        String trandeno = Tools.getCurrentTimeByFormat("yyyyMMdd") + IdWorker.getIdStr();
        //当前时间
        Integer now = DateUtil.getNowTime();

        if(dingWarningGroupBuyMsgDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }

        if(dingWarningGroupBuyMsgDto.getPayType() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入支付类型");
        }

        DingWarningGroup dingWarningGroup = dingWarningGroupMapper.queryDingWarningGroupById(dingWarningGroupBuyMsgDto.getId());
        if(dingWarningGroup == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该钉钉报警群不存在");
        }

        //按年购买价格
        DingWarningGroupBuyMsgPriceVo dingWarningGroupBuyMsgPriceVo = findBuyMsgPrice();
        if(dingWarningGroupBuyMsgPriceVo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先设置购买价格");
        }

        Double price = dingWarningGroupBuyMsgPriceVo.getPrice();
        //单次购买消息数
        Integer buyMsgNum = dingWarningGroupBuyMsgPriceVo.getBuyMsgNum();
        //购买次数
        Integer quantity = 1; //默认购买一次
        //总金额=单价*购买次数
        Double amount = Math.mul(price, quantity);
        //消息总次数
        Integer msgTotal = buyMsgNum * quantity;

        //判断支付类型
        if(dingWarningGroupBuyMsgDto.getPayType().intValue() == PaymentTypeEnum.PAY_ALIPAY.getId().intValue()) {//支付宝支付
            //添加支付宝账单
            AlipayDetail alipayDetail = new AlipayDetail();
            alipayDetail.setId(IdWorker.getId());
            alipayDetail.setMerId(dingWarningGroupBuyMsgDto.getMerId());
            alipayDetail.setTradeno(trandeno);
            alipayDetail.setType(AlipayTypeEnum.DING_WARNING_GROUP_MSG_BUY.getId()); //顶顶报警群购买消息
            //业务信息
            DingWarningGroupMsgBuyBusinessInfo dingWarningGroupMsgBuyBusinessInfo = new DingWarningGroupMsgBuyBusinessInfo();
            dingWarningGroupMsgBuyBusinessInfo.setDingWarningGroupId(dingWarningGroup.getId());
            dingWarningGroupMsgBuyBusinessInfo.setQuantity(quantity);
            dingWarningGroupMsgBuyBusinessInfo.setMsgNum(msgTotal);
            dingWarningGroupMsgBuyBusinessInfo.setPrice(price);
            dingWarningGroupMsgBuyBusinessInfo.setAmount(amount);
            dingWarningGroupMsgBuyBusinessInfo.setMsgTotal(msgTotal);
            alipayDetail.setBusinessInfo(Tools.getStrEmpty(JSONObject.toJSONString(dingWarningGroupMsgBuyBusinessInfo)));
            alipayDetail.setAmount(amount);
            alipayDetail.setStatus(AlipayStatusEnum.WAIT_BUYER_PAY.getId()); //等待付款
            alipayDetail.setCreateTime(now);
            alipayDetail.setUpdateTime(now);

            //请求支付宝申请订单
            AlipayDetailCreateDto alipayDetailCreateDto = new AlipayDetailCreateDto();
            alipayDetailCreateDto.setOutTradeNo(alipayDetail.getTradeno());
            alipayDetailCreateDto.setTotalAmount(alipayDetail.getAmount());
            alipayDetailCreateDto.setSubject(AlipayTypeEnum.DING_WARNING_GROUP_MSG_BUY.getDesc());
            String alipayUrl = alipayDetailService.createAlipayDetail(alipayDetailCreateDto);
            if(StringUtils.isNotBlank(alipayUrl)){
                alipayDetail.setAlipayUrl(alipayUrl);
                //插入支付宝账单
                alipayDetailMapper.insertSelective(alipayDetail);
                //返回支付页面
                dingWarningGroupBuyMsgVo.setAlipayUrl(uzaiConsoleSysConfig.getAlipayPaypageUrl()+"?id=" + alipayDetail.getId());
            }else{
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "调用支付宝失败");
            }
        }
        return dingWarningGroupBuyMsgVo;
    }
}
